/////////////////////////////////////////////////////////////////////////////
// Name:        mainframe.cpp
// Purpose:     
// Author:      Brant Young
// Modified by: 
// Created:     Mon May 14 21:45:58 2007
// RCS-ID:      
// Copyright:   Copyright (c) daodict.com 2007
// Licence:     GPL 2.0
/////////////////////////////////////////////////////////////////////////////

#include <wx/wx.h>
#include <wx/imaglist.h>

#include "dictmgr.h"
#include "thememgr.h"
#include "cfgmgr.h"
#include "core/events.h"
#include "mainframe.h"
#include "taskbaricon.h"
#include "maintoolbar.h"
#include "mainnb.h"
#include "notebooks/wordswnd.h"

/**
 * MainFrame constructors
 */
MainFrame::MainFrame(int w, int h) : wxFrame(NULL, ID_MAIN_FRAME, _T("Daodict"), \
                                 wxDefaultPosition, wxSize(w,h), \
                                 wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU| \
                                 wxCLOSE_BOX|wxMAXIMIZE_BOX|wxMINIMIZE_BOX)
{
	wxLogMessage(_T("MainFrame::MainFrame"));
    
    p_dictmgr = &DictManager::get();
    p_thememgr = &ThemeManager::get();
    p_cfgmgr = &ConfigManager::get();
    // _search_ctrl_no_sel = true;
    
    _p_taskbar_icon = new TaskBarIcon(this);
    
	
    p_main_toolbar = new MainToolBar(this);
    this->SetToolBar(p_main_toolbar);

    wxStatusBar* p_main_statusbar = new wxStatusBar(this, ID_MAIN_STATUSBAR, wxST_SIZEGRIP);
    p_main_statusbar->SetFieldsCount(1);
    // int sb_style = wxSB_FLAT;
    // p_main_statusbar->SetStatusStyles(1, &sb_style);
    this->SetStatusBar(p_main_statusbar);
    
    //p_main_sizer = new wxBoxSizer(wxHORIZONTAL);
    //this->SetSizer(p_main_sizer);
    p_main_spltwnd = new wxSplitterWindow(this, \
            ID_MAIN_SPLTWND, \
            wxDefaultPosition, wxDefaultSize, \
            wxNO_BORDER|wxTAB_TRAVERSAL);
    
    // ------ Input & Search panel ------------------------------------------
    p_search_panel = new wxPanel(p_main_spltwnd,ID_SEARCH_PANEL);
    //p_main_sizer->Add(p_search_panel,0,wxGROW,0);
    //p_main_sizer->SetItemMinSize(p_search_panel,160,1);
    
    p_search_sizer = new wxBoxSizer(wxVERTICAL);
    p_search_panel->SetSizer(p_search_sizer);
    
    // ==== Words Search Control ==
    p_search_ctrl = new wxSearchCtrl(p_search_panel, ID_SEARCH_CTRL, _T(""), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
    p_search_ctrl->SetToolTip(_("Search the word"));
    // Search control text style
    wxFont font;
    font.SetPointSize(11);
    p_search_ctrl->SetFont(font);
    // p_search_ctrl->SetForegroundColour(wxColour(_T("#8E2206")));
    p_search_sizer->Add(p_search_ctrl, 0, wxEXPAND|wxTOP, 2);
    
    // ==== Candidate Words List ==
    // p_words_list_lbox = new wxListBox(p_search_panel,ID_WORDS_LIST_LBOX);
    wxImageList* p_wordslist_imglist = new wxImageList(16, 16);
    wxBitmap& bmp = p_thememgr->get_bitmap(_T("wordslist-16.png"));
    p_wordslist_imglist->Add(bmp);
    
    p_words_list_lbox = new wxListView(p_search_panel, ID_WORDS_LIST_LBOX, wxDefaultPosition, wxDefaultSize, \
    					wxLC_REPORT|wxLC_ALIGN_LEFT|wxLC_SINGLE_SEL|wxLC_NO_HEADER|wxSUNKEN_BORDER); // wxSIMPLE_BORDER
    p_words_list_lbox->SetImageList(p_wordslist_imglist, wxIMAGE_LIST_SMALL);
    p_words_list_lbox->InsertColumn(0, _("Words List"));
    //p_words_list_lbox->SetColumnWidth(0, 130);
    p_search_sizer->Add(p_words_list_lbox, 1, wxEXPAND|wxTOP, 2);
    
    p_main_notebook = new MainNotebook(p_main_spltwnd);
    //p_main_sizer->Add(p_main_notebook,1,wxEXPAND,0);
    
    p_main_spltwnd->Initialize(p_search_panel);
    p_main_spltwnd->Initialize(p_main_notebook);
    p_main_spltwnd->SplitVertically(p_search_panel,p_main_notebook);
    p_main_spltwnd->SetSashGravity(0.0);
    p_main_spltwnd->SetMinimumPaneSize(2);
    
    Centre();
    InitEvents();
}


/**
 * MainFrame destructor
 */
MainFrame::~MainFrame() {
	wxLogMessage(_T("MainFrame::~MainFrame"));
	
	p_cfgmgr->Write(_T("/Window/MainFrame/width"), this->GetSize().GetWidth());
	p_cfgmgr->Write(_T("/Window/MainFrame/height"), this->GetSize().GetHeight());
	
	p_cfgmgr->Write(_T("/Window/WordsList/sash-pos"), p_main_spltwnd->GetSashPosition());
	delete _p_taskbar_icon;
}


void MainFrame::relayout() {
    p_main_spltwnd->SetSashPosition(p_cfgmgr->Read( \
    		_T("/Window/WordsList/sash-pos"), 160));
    _prev_sash_pos = p_cfgmgr->Read( \
    		_T("/Window/WordsList/sash-pos"), 160);
    
    p_main_notebook->p_words_wnd->relayout();
}

void MainFrame::focus_search_ctrl() {
    // _search_ctrl_no_sel = false;
	p_search_ctrl->SetFocusFromKbd();
}


void MainFrame::InitEvents() {
	this->Connect(ID_MAIN_FRAME, wxEVT_DAODICT_MAINFRAME_CREATED, 
			(wxObjectEventFunction)&MainFrame::OnMainFrameCreated);
	
	this->Connect(ID_SEARCH_CTRL, wxEVT_COMMAND_TEXT_ENTER, 
			(wxObjectEventFunction)&MainFrame::OnSearchWord);
	
	this->Connect(ID_SEARCH_CTRL, wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN, 
			(wxObjectEventFunction)&MainFrame::OnSearchButton);
	
	this->Connect(ID_SEARCH_CTRL, wxEVT_COMMAND_TEXT_UPDATED, 
			(wxObjectEventFunction)&MainFrame::OnWordUpdated);
	
	this->Connect(wxEVT_CLOSE_WINDOW, (wxObjectEventFunction)&MainFrame::OnCloseWnd);
	
	this->Connect(ID_WORDS_LIST_LBOX, wxEVT_COMMAND_LIST_ITEM_SELECTED, 
			(wxObjectEventFunction)&MainFrame::OnWordSelected);

	this->Connect(ID_MAIN_SPLTWND, wxEVT_COMMAND_SPLITTER_DOUBLECLICKED, 
			(wxObjectEventFunction)&MainFrame::OnSplitUnsplit);
	
	// -------------------- for search ctr -------------------------------
	wxTextCtrl* p_text = (wxTextCtrl*)(p_search_ctrl->m_text);
	p_text->Connect(wxEVT_KEY_DOWN, (wxObjectEventFunction)&MainFrame::OnSrchctrlDownKeyPress);
	p_text->Connect(wxEVT_SET_FOCUS, (wxObjectEventFunction)&MainFrame::OnSrchctrlSetFocus);
	p_text->Connect(wxEVT_KILL_FOCUS, (wxObjectEventFunction)&MainFrame::OnSrchctrlKillFocus);
	p_text->Connect(wxEVT_LEFT_DOWN, (wxObjectEventFunction)&MainFrame::OnSrchctrlClicked);

	p_words_list_lbox->Connect(wxEVT_KEY_DOWN, (wxObjectEventFunction)&MainFrame::OnWordsListUpKeyPress);
	
    // accelerator
	this->Connect(ID_MOVE_TO_WORDS_LIST, wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)&MainFrame::OnMoveToWordsList);
	this->Connect(ID_MOVE_TO_WORDS_INPUT, wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)&MainFrame::OnMoveToWordsInput);
	this->Connect(ID_MOVE_TO_WORDS_INPUT2, wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)&MainFrame::OnMoveToWordsInput2);
	this->Connect(ID_MOVE_TO_WORDS_INPUT3, wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)&MainFrame::OnMoveToWordsInput3);
}


void MainFrame::OnSrchctrlClicked(wxMouseEvent& event) {
	// wxMessageBox(_("clikced"));
    // _search_ctrl_no_sel = false;
	event.Skip();
}


// accelerator
void MainFrame::OnMoveToWordsList(wxCommandEvent& event) {
	long index = p_words_list_lbox->GetFirstSelected();
	if (index>0) {
		p_words_list_lbox->Select(index);
		p_words_list_lbox->Focus(index);
	} else {
		p_words_list_lbox->Select(0);
		p_words_list_lbox->Focus(0);
	}
	
	int count = p_words_list_lbox->GetItemCount();
	
	if (count>0) {
		p_words_list_lbox->SetFocusFromKbd();
	} else {
		p_search_ctrl->SetSelection(-1,-1);
	}
	
	event.Skip();
}
void MainFrame::OnMoveToWordsInput(wxCommandEvent& event) {
	long index = p_words_list_lbox->GetFirstSelected();
	
	if (0==index) {
		p_search_ctrl->SetSelection(-1,-1);
		p_search_ctrl->SetFocusFromKbd();
	}
}
void MainFrame::OnMoveToWordsInput2(wxCommandEvent& event) {
	p_search_ctrl->SetSelection(-1,-1);
	p_search_ctrl->SetFocusFromKbd();
}
void MainFrame::OnMoveToWordsInput3(wxCommandEvent& event) {
	//p_search_ctrl->SetSelection(-1,-1);
	p_search_ctrl->Clear();
	p_search_ctrl->SetFocus();
	int key = event.GetExtraLong();
	p_search_ctrl->SetSelection(-1,-2);
	p_search_ctrl->SetInsertionPointEnd();
	p_search_ctrl->WriteText(wxChar(key));
	p_search_ctrl->WriteText(wxChar(key));
}


void MainFrame::OnMainFrameCreated(wxCommandEvent& event) {
	// p_dictmgr->query_candidate_words(_("a"), p_words_list_lbox);
	p_search_ctrl->SetFocusFromKbd();
	p_dictmgr->query_candidate_words(_("a"), p_words_list_lbox);
	p_search_ctrl->WriteText(_T(""));
	// p_search_ctrl->SetSelection(-1,-1);
}

void MainFrame::OnSearchButton(wxCommandEvent& event) {
    // p_search_ctrl->SetDefaultStyle(txtattr);
	event.Skip();
		
	p_search_ctrl->SetSelection(-1,-1);
}

void MainFrame::OnSearchWord(wxCommandEvent& event) {
    // p_search_ctrl->SetDefaultStyle(txtattr);
	p_search_ctrl->SetSelection(-1,-1);
	
	// comment it ? some user do not like this.
	/*long index = p_words_list_lbox->GetFirstSelected();
	if (index>0) {
		p_words_list_lbox->Select(index);
		p_words_list_lbox->Focus(index);
	} else {
		p_words_list_lbox->Select(0);
		p_words_list_lbox->Focus(0);
	}
	
	int count = p_words_list_lbox->GetItemCount();
	if (count>0) {
		p_words_list_lbox->SetFocusFromKbd();
	} else {
		p_search_ctrl->SetSelection(-1,-1);
	}*/
}


void MainFrame::OnWordSelected(wxListEvent& event) {    
	const wxString& word = event.GetText();
	p_search_ctrl->SetFocusFromKbd(); // must
	p_search_ctrl->ChangeValue(word);
	
	int wordid = p_words_list_lbox->GetItemData(event.GetIndex());
	p_main_notebook->p_words_wnd->show_dicts_by_word(wordid);
	p_main_notebook->p_words_wnd->add_word_2_history(word, wordid);

	p_words_list_lbox->SetFocusFromKbd();
    
	event.Skip();
}


void MainFrame::OnCloseWnd(wxCloseEvent& event) {
	event.Veto();
	Hide();
	// wxMessageBox(_("exit"));
	// event.Skip();
}


void MainFrame::OnWordUpdated(wxCommandEvent& event) {
	const wxString& word = p_search_ctrl->GetValue();
	
	if (word.IsEmpty()) {
		p_dictmgr->query_candidate_words(_("a"), p_words_list_lbox);
	} else {
		p_dictmgr->query_candidate_words(word, p_words_list_lbox);
		int wordid = p_words_list_lbox->GetItemData(0);
		p_main_notebook->p_words_wnd->show_dicts_by_word(wordid);
	}
	
	event.Skip();
}


void MainFrame::OnSplitUnsplit(wxSplitterEvent& event) {
	int sash_pos = p_main_spltwnd->GetSashPosition();
	
	// wxMessageBox(wxString::Format(_("%d, %d, %d, %d"),negative_sash_pos, p_spltwnd->GetSashPosition(),p_spltwnd->GetClientSize().GetWidth(), p_spltwnd->GetSashSize()));
	if (sash_pos>2) { // -> <-
		_prev_sash_pos = sash_pos;
		p_main_spltwnd->SetSashPosition(2);
	}else { // <- ->
		p_main_spltwnd->SetSashPosition(_prev_sash_pos);
	} 
}

void MainFrame::OnSrchctrlDownKeyPress(wxKeyEvent& event) {
	// wxMessageBox(_("key down"));
	event.Skip();
	int key = event.GetKeyCode();
	
	if (WXK_DOWN == key) {
		wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, ID_MOVE_TO_WORDS_LIST);
		AddPendingEvent(evt);  // can't access p_words_list_lbox directly;
		return;
	}
}

void MainFrame::OnWordsListUpKeyPress(wxKeyEvent& event) {
	// wxMessageBox(_("key up"));
	
	int key = event.GetKeyCode();
	
	if (WXK_CONTROL==key||WXK_ALT==key||WXK_SHIFT==key||WXK_CONTROL==key) {
		event.Skip();
		return;
	}
	
	if (WXK_UP == event.GetKeyCode()) {
		wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, ID_MOVE_TO_WORDS_INPUT);
		AddPendingEvent(evt);  // can't access p_words_list_lbox directly;

		event.Skip();
		return;
	}
	if (WXK_DOWN == event.GetKeyCode()) {
		event.Skip();
		return;
	}
	
	if (wxIsspace(key)) {
		wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, ID_MOVE_TO_WORDS_INPUT2);
		AddPendingEvent(evt);  // can't access p_words_list_lbox directly;
		return;
	}
	
	/*if (wxIsalnum(key)) {
		// wxMessageBox(_("dka"));
		_search_ctrl_no_sel = true;
		wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, ID_MOVE_TO_WORDS_INPUT3);
		evt.SetExtraLong(key);
		AddPendingEvent(evt);  // can't access p_words_list_lbox directly;
		return;
	}*/
}

void MainFrame::OnSrchctrlSetFocus(wxFocusEvent& event) {
	// p_search_ctrl->m_text->SetSelection(-1,-1);
	event.Skip();
	
	/*if (true==_search_ctrl_no_sel) {
		return;
	}*/
	
	wxCommandEvent evt(wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN, ID_SEARCH_CTRL);
	AddPendingEvent(evt);  // can't use SetSelection directly;
}


void MainFrame::OnSrchctrlKillFocus(wxFocusEvent& event) {
	//p_search_ctrl->SetSelection(-1,0);
	event.Skip();
}
